#ifndef QNMEA0183PACKAGE_H
#define QNMEA0183PACKAGE_H
#include <QByteArray>

typedef struct {
    struct {                    // UTC时间
        quint8 hour;
        quint8 minute;
        quint8 second;
        quint16 msecond;
    } utcTime;
    char rawLatitude[20];
    double latitude;            // 纬度
    char nsFlag;                // 南北纬标志
    char rawLongitude[20];
    double longitude;           // 经度
    char ewFlag;                // 东西经标志
    quint8 flag;                // 定位指示，非0为定位成功
    quint8 satelliteNum;        // 卫星数量，0~12
    float hdop;                 // 水平精度，0.5~99.9
    float radioAltitude;        // 天线的海拔高度，-9999.9~9999.9
    float groundAltitude;       // 大地椭球面相对海平面的高度，-999.9~9999.9
} GGAPackage;

typedef struct {
    char maMode;                // 模式：M = 手动， A = 自动。
    quint8 mode;                // 模式：1:定位无效 2:2D定位 3:3D定位
    quint8 radioNum[12];        // 第N个信道正在使用的卫星PRN码编号,01~32
    float pdop;                 // 位置精度，0.5~99.9
    float hdop;                 // 水平精度，0.5~99.9
    float vdop;                 // 垂直精度，0.5~99.9
} GSAPackage;

typedef struct {
    int satId;                  // 卫星ID
    int angleOfElevation;       // 仰角，最大90
    int angleOfDirection;       // 方位角，0~359
    int cNo;                    // 信噪比，0~99db
} SatelliteInfo;

typedef struct {
    int msgCount;               // 消息数目，1~3
    int msgIndex;               // 消息编号
    int satelliteNum;           // 卫星数量
    SatelliteInfo satellites[4];
} GSVPackage;

typedef struct {
    struct {                    // UTC时间
        quint8 hour;
        quint8 minute;
        quint8 second;
        quint16 msecond;
    } utcTime;
    char flag;                  // 状态，A有效，V无效
    char rawLatitude[20];
    double latitude;            // 纬度
    char nsFlag;                // 南北纬标志
    char rawLongitude[20];
    double longitude;           // 经度
    char ewFlag;                // 东西经标志
    float speed;                // 地面速度，单位Nnot(节)
    float direction;            // 地面航向，000.0~359.9，以真北为参考基准
    struct {
        int day;
        int month;
        int year;
    } utcDate;
} RMCPackage;

typedef struct {
    float directionT;           // 以真北为参考基准的地面航向，000~359度
    float directionM;           // 以磁北为参考基准的地面航向
    float speed;                // 地面速度，000.0~999.9节
    float speedKMH;             // 地面速度，0000.0~1851.8公里/小时
    char modeFlag;              // 模式指示(仅3.0输出)，A=自主定位，D=差分，E=估算，N=数据无效
} VTGPackage;

class QNmea0183Package
{
public:
    enum PackageType {
        GGA, GSA, GSV,
        RMC, VTG, ZDA,
        Invalid
    };

    QNmea0183Package(const QByteArray &data);

    PackageType type() const { return _type; }

    const GGAPackage &ggaInformation() const { return _pkgBody.ggaInfo; }
    const GSAPackage &gsaInformation() const { return _pkgBody.gsaInfo; }
    const GSVPackage &gsvInformation() const { return _pkgBody.gsvInfo; }
    const RMCPackage &rmcInformation() const { return _pkgBody.rmcInfo; }
    const VTGPackage &vtgInformation() const { return _pkgBody.vtgInfo; }

private:
    void fromRaw(const QByteArray &data);

private:
    PackageType _type;
    union {
        GGAPackage ggaInfo;
        GSAPackage gsaInfo;
        GSVPackage gsvInfo;
        RMCPackage rmcInfo;
        VTGPackage vtgInfo;
    } _pkgBody;
};

#endif // QNMEA0183PACKAGE_H
